package com.hujiang.basic.search.fullindex;

import com.hujiang.basic.search.handler.impl.model.FullIndexRquest;
import com.hujiang.basic.search.handler.impl.model.FullIndexTask;
import com.hujiang.basic.search.util.IndexEsDao;
import com.hujiang.basic.search.util.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

@Slf4j
@Service
public class FullIndexServiceImpl implements FullIndexService {

    @Value("${fullIndex.ignoreSettingNames}")
    private String ignoreSettingNamesString;

    private List<String> ignoreSettingNames;

    @Autowired
    private IndexEsDao esDao;

    @Autowired
    private TaskDao taskDao;

    @Value("${fullIndex.defaultWindowSize:1000}")
    private int bulkSize;

    @Value("${fullIndex.indexRefreshInterval:10s}")
    private String indexRefreshInterval;

    @PostConstruct
    private void init() {
        if (null == this.ignoreSettingNamesString) {
            this.ignoreSettingNames = new ArrayList<>();
        } else {
            this.ignoreSettingNames = Arrays.asList(this.ignoreSettingNamesString.split(","));
        }
    }

    @Override
    public Integer triggerFullIndex(FullIndexRquest req) {
        log.info(req.toString());

        String index = esDao.getIndexName(req.getIndexName());
        String nodeName = IpUtils.getNodeAddr();
        int size = 0 < req.getSize() ? req.getSize() : bulkSize;
        FullIndexTask task = FullIndexTask.buildDefault(req, index, size, nodeName);

        Map<String, String> settings = esDao.getIndexSettings(index);
        esDao.createIndex(task.getNewIndex(), esDao.getIndexMappings(index), this.filterSettings(settings));
        taskDao.createTask(task);

        return task.getTaskId();
    }

    private Map<String, String> filterSettings(Map<String, String> settings) {
        Map<String, String> map = new HashMap<>();
        if (settings != null) {
            for (Map.Entry<String, String> setting : settings.entrySet()) {
                if (ignoreSettingNames.stream().noneMatch(o -> StringUtils.equalsIgnoreCase(setting.getKey(), o))) {
                    map.put(setting.getKey(), setting.getValue());
                }
            }
        }
        return map;
    }
}
